/**
 *
 */
package com.gitee.wsl.text.dictomaton

/**
 *
 * This class provides information about the state in which transitions for a given character sequence
 * ended up when computing the hash code of this sequence in a [PerfectHashDictionary].
 *
 * It is possible to resume a transition using a StateInfo object to define the start state in [PerfectHashDictionary.getStateInfo]
 *
 * Example:
 * <pre>
 * `PerfectHashDictionary dict; // dictionary containing sequences "abc" and "abc def"
 * String seq = "abc def";
 *
 * StateInfo info1 = dict.getStateInfo(seq.subSequence(0, 3));
 *
 * if (info1.isInFinalState()) {
 * int hash1 = info1.getHash(); // hash1 contains the hash for "abc"
 * }
 *
 * if (info1.isInKnownState()) {
 *
 * // regardless of whether we are in a final state after "abc", as long as
 * // we are in a known state (= the sequence is contained in the dictionary)
 * // we can resume the transition after "abc"
 *
 * StateInfo info2 = dict.getStateInfo(seq.subSequence(3, seq.length()), info1);
 * if (info2.isInFinalState()) {
 * int hash2 = info2.getHash(); // hash2 contains the hash for "abc def"
 * }
 * }
 *
` *
</pre> *
 *
 * @author René Kriegler
 */
class StateInfo internal constructor(num: Int, state: Int, trans: Int, inFinalState: Boolean) {
    var num: Int = 0
    var state: Int = 0
    var trans: Int = -1
    var inFinalState: Boolean = false

    init {
        this.num = num
        this.state = state
        this.trans = trans
        this.inFinalState = inFinalState
    }

    val isInKnownState: Boolean
        /**
         *
         * @return true iff the character sequence that lead to this state is a character sequence or a prefix of a character sequence in the dictionary
         */
        get() = trans > -1

    /**
     *
     * @return true iff the character sequence that lead to this state is a character sequence in the dictionary
     */
    fun isInFinalState(): Boolean {
        return this.isInKnownState && inFinalState
    }

    val hash: Int
        /**
         *
         * @return the hash code of the character sequence that lead to this state
         * @throws IllegalStateException if the current state is not a final state.
         */
        get() {
            check(isInFinalState()) { "Not in final state" }
            return num + 1
        }
}
